import { Renderer } from "@k8slens/extensions";
import React from "react";
import { makeObservable, computed, observable, action } from "mobx";
import { observer } from "mobx-react";
const {
  Component: { Button },
  K8sApi: { podsApi, serviceApi, ingressApi },
} = Renderer;
import "./ingress-check.scss";
import tls, { PeerCertificate } from "tls";
import net from "net";
import { ingressCheckPreferencesStore } from "./preference/preference-store";
import writeXlsxFile from "write-excel-file";
@observer
export class IngressCheckPage extends React.Component<{
  extension: Renderer.LensExtension;
}> {
  @observable private resultList: object[] = [];
  @observable private checking = false;
  
  // 排序相关状态
  @observable private sortField: string = '';
  @observable private sortDirection: 'asc' | 'desc' = 'asc';

  constructor(props: any) {
    super(props);
    makeObservable(this);
  }

  // 计算属性：排序后的结果列表
  @computed
  get sortedResultList() {
    return this.sortField
      ? [...this.resultList].sort((a, b) => {
        const aValue = a[this.sortField as keyof object];
        const bValue = b[this.sortField as keyof object];
        let comparison = 0;
        if (aValue < bValue) comparison = -1;
        else if (aValue > bValue) comparison = 1;
        return this.sortDirection === 'desc' ? -comparison : comparison;
      })
      : this.resultList;
  }

  // 排序方法
  @action
  private sort = (field: string) => {
      if (field === this.sortField) {
        this.sortDirection = this.sortDirection === 'asc' ? 'desc' : 'asc';
      } else {
        this.sortField = field;
        this.sortDirection = 'asc';
      }
    };

  render() {
    return (
      <div className="ingress-check-container">
        <p>
          <Button
            disabled={this.checking}
            onClick={() => this.checkAllIngress()}
          >
            Check Ingress {this.checking ? "(Checking...)" : ""}
          </Button>
          {/* 添加导出按钮 */}
          <Button 
            onClick={() => this.exportToExcel()}
            style={{ marginLeft: '10px' }}
          >
            Export to Excel
          </Button>
          
          <table className="ingress-check-table">
            <thead>
              <tr>
                <th onClick={() => this.sort('name')}>
                  Name {this.sortField === 'name' && (this.sortDirection === 'asc' ? '↑' : '↓')}
                </th>
                <th onClick={() => this.sort('namespace')}>
                  Namespace {this.sortField === 'namespace' && (this.sortDirection === 'asc' ? '↑' : '↓')}
                </th>
                <th onClick={() => this.sort('error')}>
                  Error {this.sortField === 'error' && (this.sortDirection === 'asc' ? '↑' : '↓')}
                </th>
              </tr>
            </thead>
            <tbody>
              {this.sortedResultList.map((item, index) => ( // 添加key属性
                <tr key={index}>
                  <td>{item["name"]}</td>
                  <td>{item["namespace"]}</td>
                  <td>{item["error"]}</td>
                </tr>
              ))}
            </tbody>
          </table>
        </p>
      </div>
    );
  }

  // 原有方法保持不变（添加action装饰器）
  @action
  // 在checkAllIngress方法中修改：
  async checkAllIngress() {
    this.checking = true;
    const ingressList = await ingressApi.list();
    const resultList: any[] = [];
    
    for (const ingress of ingressList) {
      // TLS证书检查
      if (ingress.spec.tls) {
        if (ingress.spec.tls.length === 0) {
          resultList.push({
            name: ingress.metadata.name,
            namespace: ingress.metadata.namespace,
            error: "ingress has no TLS configuration",
            ingress: ingress,
          });
        }
        
        for (const tlsConfig of ingress.spec.tls) {
          if (tlsConfig.secretName) {
            let secret: Renderer.K8sApi.Secret = null;
            
            try {
              secret = await Renderer.K8sApi.secretsApi.get({
                namespace: ingress.metadata.namespace,
                name: tlsConfig.secretName,
              });
            } catch (e) {
              console.log(e);
            }

            if (!secret) {
              resultList.push({
                name: ingress.metadata.name,
                namespace: ingress.metadata.namespace,
                error: `Secret ${tlsConfig.secretName} does not exist`,
                ingress: ingress,
              });
            } else {
              const secretKeys = secret.getKeys();
              for (const key of secretKeys) {
                const certStr = Buffer.from(
                  secret.data[key],
                  "base64"
                ).toString("ascii");

                if (!certStr.startsWith("-----BEGIN CERTIFICATE-----")) continue;

                try {
                  const secureContext = tls.createSecureContext({ cert: certStr });
                  const secureSocket = new tls.TLSSocket(new net.Socket(), {
                    secureContext,
                  });
                  const cert: PeerCertificate = secureSocket.getCertificate() as PeerCertificate;
                  const expiryDate = new Date(cert.valid_to);
                  const now = new Date();
                  // 确保使用响应式的store值
                  const nDays = ingressCheckPreferencesStore.expiryDays * 24 * 60 * 60 * 1000;
                  
                  if (expiryDate <= new Date(now.getTime() + nDays)) {
                    resultList.push({
                      name: ingress.metadata.name,
                      namespace: ingress.metadata.namespace,
                      error: `Certificate‘s Expires is less than <${ingressCheckPreferencesStore.expiryDays} days (Expires: ${expiryDate.toISOString()})`,
                      ingress: ingress,
                    });
                  }
                } catch (e) {
                  console.error(e);
                }
              }
            }
          }
        }
      }
      if (ingress.spec.rules) {
        for (let j = 0; j < ingress.spec.rules.length; j++) {
          const rule = ingress.spec.rules[j];
          if (ingress.spec.tls) {
            if (!rule.host) {
              resultList.push({
                name: ingress.metadata.name,
                namespace: ingress.metadata.namespace,
                error: "https protocol but no host",
                ingress: ingress,
              });
            }
          }

          if (rule.http && rule.http.paths) {
            for (let j = 0, l = rule.http.paths.length; j < l; j++) {
              const path = rule.http.paths[j];
              if (path.backend && path.backend["service"]) {
                let serviceObject: Renderer.K8sApi.Service = null;
                try {
                  serviceObject = await Renderer.K8sApi.serviceApi.get({
                    name: path.backend["service"].name,
                    namespace: ingress.getNs(),
                  });
                } catch (e) {
                  console.log(e);
                }

                if (!serviceObject) {
                  resultList.push({
                    name: ingress.metadata.name,
                    namespace: ingress.metadata.namespace,
                    error:
                  "service " +
                  path.backend["service"].name +
                  " is not exist",
                    ingress: ingress,
                  });
                }
              }
            }
          }
        }
      }
    }
    this.resultList = resultList;
    this.checking = false;
  }
  
  async exportToExcel() {
    const schema = [
      {
        column: "Name",
        type: String,
        value: (s) => s["name"],
      },
      {
        column: "Namespace",
        type: String,
        value: (s) => s["namespace"],
      },
      {
        column: "Error",
        type: String,
        value: (s) => s["error"],
      },
      {
        column: "Check Time",
        type: Date,
        format: 'yyyy-mm-dd hh:mm:ss',
        value: () => new Date(),
      }
    ];
    
    await writeXlsxFile(this.sortedResultList, {
      schema,
      fileName: "ingress_check_results.xlsx",
    });
  }
}

// 图标组件
export function IngressCheckIcon(props: Renderer.Component.IconProps) {
  return (
    <Renderer.Component.Icon
      {...props}
      material="security"
      tooltip="IngressCheck"
    />
  );
}